"""
PicknBuy24批量处理任务
"""
from typing import List, Dict, Any
import asyncio
from axiom_boot.task import task
from axiom_boot.scraper import ScraperEngine, Target
from axiom_boot.logging.setup import get_logger

from ...vehicle.service.vehicle_service import VehicleService
from ...scraper.services.scraper_failed_record_service import ScraperFailedRecordService
from ...scraper.extractors.picknbuy24_extractor.list_page_extractor import VehicleUrlItem

from .helpers.scrapers import scrape_picknbuy24_vehicles_details_with_failure_record

logger = get_logger(__name__)


@task(name="batch_scrape_vehicle_details_by_refs", timeout=1800)
async def batch_scrape_vehicle_details_by_refs(
    vehicle_refs: List[Dict[str, str]],  # 现在可以正常使用泛型类型注解了
    task_id: str,
    parent_task_id: str,
    vehicle_service: VehicleService,
    engine: ScraperEngine,
    failed_record_service: ScraperFailedRecordService
) -> dict:
    """
    批量爬取指定ref_no车辆的详情信息
    
    Args:
        vehicle_refs: 车辆信息列表，每个包含 ref_no, url, title, vehicle_type
        task_id: 当前任务ID
        parent_task_id: 父任务ID（增量更新任务）
        vehicle_service: 车辆服务
        engine: 爬虫引擎
        failed_record_service: 失败记录服务
    """
    logger.info(f"【{task_id}】开始批量爬取{len(vehicle_refs)}辆车的详情信息")
    
    success_count = 0
    failed_count = 0
    
    try:
        # 转换为VehicleUrlItem格式，复用现有逻辑
        vehicle_items = []
        for ref_info in vehicle_refs:
            item = VehicleUrlItem(
                url=ref_info['url'],
                ref_no=ref_info['ref_no'],
                title=ref_info.get('title', ''),
                vehicle_type=ref_info.get('vehicle_type', '')
            )
            vehicle_items.append(item)
        
        # 【复用现有逻辑】使用现有的批量详情爬取函数
        vehicles_data = await scrape_picknbuy24_vehicles_details_with_failure_record(
            vehicle_items, engine, failed_record_service, task_id
        )
        
        if vehicles_data:
            logger.info(f"🔄 【{task_id}】准备批量保存 {len(vehicles_data)} 辆车的详情数据...")
            # 批量保存到数据库
            saved_count = await vehicle_service.batch_save_vehicles_only(
                vehicles_data,
                source="picknbuy24",
                update_existing=True
            )
            
            success_count = saved_count
            failed_count = len(vehicle_refs) - saved_count
            
            logger.info(f"✅ 【{task_id}】批量详情爬取完成！成功保存 {success_count} 辆，失败 {failed_count} 辆")
        else:
            failed_count = len(vehicle_refs)
            logger.warning(f"【{task_id}】批量详情爬取无有效结果")
        
        return {
            "success": True,
            "task_id": task_id,
            "parent_task_id": parent_task_id,
            "total_vehicles": len(vehicle_refs),
            "success_count": success_count,
            "failed_count": failed_count,
            "success_rate": (success_count / len(vehicle_refs)) * 100 if vehicle_refs else 0
        }
        
    except Exception as e:
        logger.error(f"【{task_id}】批量详情爬取任务失败: {e}")
        return {
            "success": False,
            "task_id": task_id,
            "parent_task_id": parent_task_id,
            "error": str(e),
            "total_vehicles": len(vehicle_refs),
            "success_count": 0,
            "failed_count": len(vehicle_refs)
        }


@task(name="batch_verify_sold_vehicles_by_refs", timeout=1200)
async def batch_verify_sold_vehicles_by_refs(
    ref_nos: List[str],  # 现在可以正常使用泛型类型注解了
    task_id: str,
    parent_task_id: str,
    vehicle_service: VehicleService,
    engine: ScraperEngine
) -> dict:
    """
    批量验证指定ref_no车辆的售出状态
    
    Args:
        ref_nos: 需要验证的车辆ref_no列表
        task_id: 当前任务ID
        parent_task_id: 父任务ID（增量更新任务）
        vehicle_service: 车辆服务
        engine: 爬虫引擎
    """
    logger.info(f"【{task_id}】开始批量验证{len(ref_nos)}辆车的售出状态")
    
    verified_sold_count = 0
    skipped_count = 0
    
    try:
        # 获取需要验证的车辆信息
        vehicles_to_verify = []
        for ref_no in ref_nos:
            try:
                vehicle = await vehicle_service.find_one_by_filters(ref_no=ref_no)
                if vehicle and vehicle.status_tag in ['normal', 'sale', 'new']:
                    vehicles_to_verify.append((ref_no, vehicle))
                else:
                    skipped_count += 1
            except Exception as e:
                logger.warning(f"【{task_id}】获取车辆{ref_no}信息失败: {e}")
                skipped_count += 1
        
        if not vehicles_to_verify:
            logger.info(f"【{task_id}】无需验证的车辆")
            return {
                "success": True,
                "task_id": task_id,
                "parent_task_id": parent_task_id,
                "total_refs": len(ref_nos),
                "verified_sold": 0,
                "skipped": len(ref_nos)
            }
        
        # 【复用轻量级验证逻辑】并发验证售出状态
        from ...scraper.extractors.picknbuy24_extractor.lightweight_sold_verifier import LightweightSoldVerifier
        
        async def verify_single_vehicle(ref_no: str, vehicle) -> bool:
            """验证单个车辆，返回是否确认售出"""
            try:
                detail_url = vehicle.detail_url
                target = Target(url=detail_url, extractor=LightweightSoldVerifier())
                
                results = await engine.scrape(target)
                
                if not results:
                    return True  # 无响应视为售出
                
                for result in results:
                    if hasattr(result, 'is_sold') and hasattr(result, 'is_accessible'):
                        if not result.is_accessible or result.is_sold:
                            return True  # 确认售出
                
                return False  # 仍可访问且未售出
                
            except Exception as e:
                logger.warning(f"【{task_id}】验证车辆{ref_no}时出错: {e}")
                return False  # 出错时保守处理
        
        # 并发验证，限制并发数
        semaphore = asyncio.Semaphore(20)  # 20个并发
        
        async def verify_with_limit(ref_no: str, vehicle):
            async with semaphore:
                return await verify_single_vehicle(ref_no, vehicle)
        
        # 执行并发验证
        verify_tasks = [verify_with_limit(ref_no, vehicle) 
                       for ref_no, vehicle in vehicles_to_verify]
        verify_results = await asyncio.gather(*verify_tasks, return_exceptions=True)
        
        # 收集确认售出的车辆并批量更新
        confirmed_sold_vehicles = []
        for i, result in enumerate(verify_results):
            if isinstance(result, Exception):
                continue
            if result:  # 确认售出
                ref_no, vehicle = vehicles_to_verify[i]
                confirmed_sold_vehicles.append(vehicle.id)
        
        # 批量更新售出状态
        if confirmed_sold_vehicles:
            logger.info(f"🔄 【{task_id}】准备批量更新 {len(confirmed_sold_vehicles)} 辆车为售出状态...")
            updated_count = await vehicle_service.batch_update_vehicle_status(
                vehicle_ids=confirmed_sold_vehicles,
                status_tag='sold'
            )
            verified_sold_count = updated_count
            logger.info(f"✅ 【{task_id}】批量更新完成！成功标记 {verified_sold_count} 辆车为售出状态")
        
        return {
            "success": True,
            "task_id": task_id,
            "parent_task_id": parent_task_id,
            "total_refs": len(ref_nos),
            "verified_sold": verified_sold_count,
            "skipped": skipped_count,
            "success_rate": (verified_sold_count / len(vehicles_to_verify)) * 100 if vehicles_to_verify else 0
        }
        
    except Exception as e:
        logger.error(f"【{task_id}】批量售出验证任务失败: {e}")
        return {
            "success": False,
            "task_id": task_id,
            "parent_task_id": parent_task_id,
            "error": str(e),
            "total_refs": len(ref_nos),
            "verified_sold": 0,
            "skipped": 0
        }
